package org.despair2D.ui.puppet 
{
	import flash.text.TextFormat;
	import org.despair2D.renderer.IView;
	import org.despair2D.ui.core.Component;
	
	import org.despair2D.core.ns_despair;
	use namespace ns_despair;
	

final public class TextPuppet extends PuppetProxy
{
	
	public function TextPuppet() 
	{
		super();
		m_view = new TextPuppetComp(this);
	}
	
	
	
	final public function get size() : int
	{ 
		return m_view.size; 
	}
	
	final public function set size( v:int ) : void 
	{
		m_view.size = v;
	}
	
	
	final public function get color() : uint
	{
		return m_view.color; 
	}
	
	final public function set color( v:uint ) : void 
	{
		m_view.color = v;
	}
	
	
	final public function get bold() : Boolean 
	{ 
		return m_view.bold;
	}
	
	final public function set bold( b:Boolean ) : void 
	{
		m_view.bold = b;
	}

	
	final public function get letterSpacing() : Number 
	{ 
		return m_view.letterSpacing;
	}
	
	final public function set letterSpacing( v:Number ) : void 
	{
		m_view.letterSpacing = v;
	}
	

	final public function get font() : String
	{ 
		return m_view.font;
	}
	
	final public function set font( v:String ) : void 
	{
		m_view.font = v;
	}
	

	final public function get text() : String
	{ 
		return m_view.text;
	}
	
	final public function set text( v:String ) : void
	{
		m_view.text = v;
	}
	
	
	final public function get background() : Boolean
	{
		return m_view.background
	}
	
	
	final public function set background( b:Boolean ) : void
	{
		m_view.background = b
	}
	
	
	
	final public function setMaxWidth( v:Number ) : void
	{
		m_view.setMaxWidth(v);
	}
	

	final public function setBackground( bgColor:uint = 0xc3F3F3,
										bgAlpha:Number = 0.5, 
										lineColor:uint = 0,
										lineAlpha:Number = 1,
										thickness:int = 0,
										ellipse:Number = 0, gapX:Number = 4, gapY:Number = 4 ) : void
	{
		m_view.setBackground(bgColor, bgAlpha, lineColor, lineAlpha, thickness, ellipse);
		m_view.m_gapX = gapX
		m_view.m_gapY = gapY
	}
	
	
	

	final override ns_despair function get view() : IView
	{
		return m_view;
	}
	
	
	final override ns_despair function recycle() : void
	{
		super.recycle();
		cachedTextPuppetList[cachedTextPuppetLength++] = this;
	}

		
	ns_despair static function getTextPuppet( text:String, offsetX:Number, offsetY:Number, embedFont:Boolean ) : TextPuppet
	{
		var T:TextPuppet = (cachedTextPuppetLength > 0 ? cachedTextPuppetLength-- : 0) ? cachedTextPuppetList.pop() : new TextPuppet();
		T.m_view.m_textFormat  =  new TextFormat();
		T.m_view.text          =  text;
		T.m_view.m_offsetX     =  offsetX;
		T.m_view.m_offsetY     =  offsetY;
		T.m_view.m_embedFonts  =  embedFont
		return T;
	}


		
	ns_despair static var cachedTextPuppetList:Array = [];
	
	ns_despair static var cachedTextPuppetLength:int;
	
	
	ns_despair var m_view:TextPuppetComp;
	
}

}

import flash.display.BitmapData;
import flash.display.Sprite;
import flash.text.TextField;
import flash.text.TextFormat;
import org.despair2D.debug.Logger;
import org.despair2D.ui.puppet.ModifiableImagePuppetComp
import org.despair2D.ui.puppet.IPuppet
import org.despair2D.ui.puppet.TextPuppet

import org.despair2D.core.ns_despair;
use namespace ns_despair;
	

final class TextPuppetComp extends ModifiableImagePuppetComp
{
	
	public function TextPuppetComp( proxy:IPuppet ) 
	{
		super(proxy);
	}

	
	
	/* 背景发生变化 */
	ns_despair static const c_bgDirtyFlag:uint  =  0x100;
	
	/* 存在背景 */
	ns_despair static const c_bgFlag:uint       =  0x200;
	
		

	/* 大小 */
	final internal function get size() : int
	{ 
		return int(m_textFormat.size); 
	}
	
	final internal function set size( v:int ) : void 
	{
		if (int(m_textFormat.size) != v)
		{
			m_textFormat.size = v;
			this.addToModifyList();
		}
	}
	
	
	/* 颜色 */
	final public function get color() : uint
	{
		return uint(m_textFormat.color); 
	}
	
	final public function set color( v:uint ) : void 
	{
		if (uint(m_textFormat.color) != v)
		{
			m_textFormat.color = v;
			this.addToModifyList();
		}
	}
	
	
	/* 粗体 */
	final public function get bold() : Boolean 
	{ 
		return Boolean(m_textFormat.bold);
	}
	
	final public function set bold( b:Boolean ) : void 
	{
		if (Boolean(m_textFormat.bold) != b)
		{
			m_textFormat.bold = b;
			this.addToModifyList();
		}
	}

	
	/* 字距 */
	final public function get letterSpacing() : Number 
	{ 
		return Number(m_textFormat.letterSpacing);
	}
	
	final public function set letterSpacing( v:Number ) : void 
	{
		if (Number(m_textFormat.letterSpacing) != v)
		{
			m_textFormat.letterSpacing = v;
			this.addToModifyList();
		}
	}
	
	
	/* 字体 */
	final public function get font() : String
	{ 
		return m_textFormat.font;
	}
	
	final public function set font( v:String ) : void 
	{
		if (m_textFormat.font != v)
		{
			m_textFormat.font = v;
			this.addToModifyList();
		}
	}
	
	
	/* 文本 */
	final public function get text() : String
	{ 
		return m_content;
	}
	
	final public function set text( v:String ) : void
	{
		if (m_content != v)
		{
			m_content = v;
			this.addToModifyList();
		}
	}
	
	
	/* 是否有背景 */
	final public function get background() : Boolean
	{
		return Boolean(m_flags & c_bgFlag)
	}
	
	
	final public function set background( b:Boolean ) : void
	{
		if (b)
		{
			m_flags |= (c_bgFlag | c_bgDirtyFlag);
		}
		
		else
		{
			m_flags &= ~(c_bgFlag | c_bgDirtyFlag);
		}
		
		this.addToModifyList()
	}
	
	
	/**
	 * 设置背景
	 * @param	bgColor
	 * @param	bgAlpha
	 * @param	lineColor
	 * @param	lineAlpha
	 * @param	thickness
	 * @param	ellipse
	 */
	final public function setBackground( bgColor:uint = 0xc3F3F3,
										bgAlpha:Number = 0.5, 
										lineColor:uint = 0,
										lineAlpha:Number = 1,
										thickness:int = 0,
										ellipse:Number = 0 ) : void
	
	{
		m_bgColor       =  bgColor;
		m_bgAlpha       =  bgAlpha;
		m_lineColor     =  lineColor;
		m_lineAlpha     =  lineAlpha;
		m_thickness     =  thickness;
		m_ellipse       =  ellipse;
	}
	
	
	/**
	 * 最大文本宽度
	 * @param	widthMax
	 */
	final public function setMaxWidth( v:Number ) : void
	{
		m_widthMax = v;
	}
	
	
	
	
	final override public function modify() : void
	{
		var w:Number, h:Number, ww:Number, hh:Number;
		
		if (!m_textField)
		{
			m_textField = new TextField()
		}
		
		m_textField.embedFonts  =  this.m_embedFonts
		m_textField.text        =  this.m_content
		m_textField.setTextFormat(m_textFormat)
		
		// width
		w =  Boolean(m_flags & c_bgFlag) ? m_textField.textWidth + 4 + (m_gapX << 1) : m_textField.textWidth + 4;
		
		// 检查最大width
		if (w > m_widthMax)
		{
			m_textField.autoSize   =  'none';
			m_textField.multiline  =  true;
			m_textField.wordWrap   =  true;
			m_textField.width      =  m_widthMax;
			w                      =  m_widthMax;
		}
		
		else
		{
			m_textField.autoSize   =  'left';
			m_textField.multiline  =  false;
			m_textField.wordWrap   =  false;
		}
		
		// height
		h =  Boolean(m_flags & c_bgFlag) ? m_textField.textHeight + 4 + (m_gapY << 1) : m_textField.textHeight + 4;
		
		// 背景调整
		if (Boolean(m_flags & c_bgFlag) && m_thickness > 0)
		{
			ww  =  ((w + m_thickness) % 1 > 0) ? w + m_thickness : int(w + m_thickness + 1);
			hh  =  ((h + m_thickness) % 1 > 0) ? h + m_thickness : int(h + m_thickness + 1);
		}
		
		else
		{
			ww  =  w;
			hh  =  h;
		}
		
		// 画像
		if ( ww != cachedWidth || hh != cachedHeight )
		{
			if (cachedImage) 
			{
				cachedImage.dispose();
			}
			
			cachedWidth   =  ww;
			cachedHeight  =  hh;
			cachedImage   =  new BitmapData(ww, hh, true, 0x0);
			m_img.x       =  m_offsetX - ww * 0.5;
			m_img.y       =  m_offsetY - hh * 0.5;
		}
		
		else
		{
			cachedImage.fillRect(cachedImage.rect, 0x0);
		}
		
		// 重绘
		if (Boolean(m_flags & c_bgFlag))
		{
			if (!m_container)
			{
				m_container = new Sprite();
				m_container.addChild(m_textField);
				//m_textField.x = ( cachedWidth - m_textField.textWidth ) * 0.5
				//m_textField.y = ( cachedHeight - m_textField.textHeight ) * 0.5
				//m_textField.x = m_gapX + m_thickness * 0.5;
				//m_textField.y = m_gapY + m_thickness * 0.5;
				m_textField.x = m_gapX + m_thickness * 0.5 + (w + m_thickness) % 1 + 0.1;
				m_textField.y = m_gapY + m_thickness * 0.5 + (h + m_thickness) % 1 + 0.1;
			}
			
			if (Boolean(m_flags & c_bgDirtyFlag))
			{
				m_container.graphics.clear();
				m_container.graphics.beginFill(m_bgColor, m_bgAlpha);
				if (m_thickness > 0)
				{
					m_container.graphics.lineStyle(m_thickness, m_lineColor, m_lineAlpha);
				}
				m_container.graphics.drawRoundRect(m_thickness * 0.5, m_thickness * 0.5, int(cachedWidth - m_thickness), int(cachedHeight - m_thickness), m_ellipse, m_ellipse);
				m_flags &= ~c_bgDirtyFlag;
			}
			
			cachedImage.draw(m_container);
		}
		
		else
		{
			cachedImage.draw(m_textField);
		}
		
		m_flags         &= ~c_addedToModifyFlag
		m_img.bitmapData = cachedImage;
	}
	
	
	
	/**
	 * 回收
	 */
	final override ns_despair function recycle() : void
	{
		if (cachedImage)
		{
			cachedImage.dispose();
			cachedImage = null;
		}
		
		super.recycle();
		m_widthMax = cachedWidth = cachedHeight = NaN;
		m_textFormat = null
		m_content = null
		m_embedFonts = false
		m_flags &= ~0xF00;
	}
	
	
	
	
	//======================
	// Member
	//======================
	
	
	ns_despair static var m_container:Sprite;

	ns_despair static var m_textField:TextField
	
	
	ns_despair var cachedImage:BitmapData;
		
	ns_despair var m_textFormat:TextFormat;

	ns_despair var m_content:String
	
	ns_despair var m_embedFonts:Boolean

	ns_despair var m_widthMax:Number;
	
	ns_despair var cachedWidth:Number;
	
	ns_despair var cachedHeight:Number;
	
	ns_despair var m_offsetX:Number;
	
	ns_despair var m_offsetY:Number;
	
	ns_despair var m_gapX:Number;
	
	ns_despair var m_gapY:Number;
	
	
	ns_despair var m_bgColor:uint;
	
	ns_despair var m_bgAlpha:Number;
	
	ns_despair var m_lineColor:uint;
	
	ns_despair var m_lineAlpha:Number;
	
	ns_despair var m_thickness:Number;
	
	ns_despair var m_ellipse:int;

}